/**
 * Session认证中间件
 * 处理用户session验证和token刷新
 */

const { refreshUserAccessToken } = require("./feishu");
const { unauthorizedResponse } = require("../middleware/responseHandler");
const logger = require("./logger");

/**
 * 检查token是否即将过期（在过期前5分钟开始刷新）
 * @param {string} loginTime - 登录时间
 * @param {number} expiresIn - 过期时间（秒）
 * @returns {boolean} 是否即将过期
 */
const isTokenExpiringSoon = (loginTime, expiresIn) => {
  const loginTimestamp = new Date(loginTime).getTime();
  const currentTime = Date.now();
  const expiresInMs = expiresIn * 1000; // 转换为毫秒
  const bufferTime = 5 * 60 * 1000; // 5分钟缓冲时间

  return currentTime - loginTimestamp >= expiresInMs - bufferTime;
};

/**
 * 检查session是否有效的中间件
 */
const checkSessionAuth = async (req, res, next) => {
  // 如果没有session认证信息，直接跳过
  if (!req.session.feishuAuth) {
    return next();
  }

  const { access_token, refresh_token, expires_in, loginTime } = req.session.feishuAuth;

  // 检查token是否即将过期
  if (isTokenExpiringSoon(loginTime, expires_in)) {
    logger.info("Token即将过期，尝试刷新");

    try {
      // 尝试刷新token
      const newTokenData = await refreshUserAccessToken(refresh_token);
      const { access_token: newAccessToken, refresh_token: newRefreshToken, expires_in: newExpiresIn } = newTokenData;

      // 更新session中的token信息
      req.session.feishuAuth = {
        access_token: newAccessToken,
        refresh_token: newRefreshToken,
        expires_in: newExpiresIn,
        loginTime: new Date().toISOString(),
      };

      // 动态调整session cookie的过期时间
      const cookieMaxAge = Math.min(newExpiresIn * 1000, 2 * 60 * 60 * 1000);
      req.session.cookie.maxAge = cookieMaxAge;

      logger.info("Token刷新成功");
    } catch (error) {
      logger.error("Token刷新失败", error);
      // 刷新失败，清除session
      req.session.destroy((err) => {
        if (err) {
          logger.error("清除session失败", err);
        }
      });
      // 不阻断请求，让业务逻辑处理未登录状态
    }
  }

  next();
};

/**
 * 要求用户已登录的中间件
 */
const requireAuth = (req, res, next) => {
  if (!req.session.feishuAuth?.access_token) {
    return unauthorizedResponse(res, "用户未登录，请重新授权");
  }
  next();
};

/**
 * 获取当前用户token的辅助函数
 * @param {Object} req - Express请求对象
 * @returns {string|null} 用户token或null
 */
const getCurrentUserToken = (req) => {
  return req.session.feishuAuth?.access_token || null;
};

module.exports = {
  checkSessionAuth,
  requireAuth,
  getCurrentUserToken,
  isTokenExpiringSoon,
}; 